#include <common.h>

#if defined(MULTIPROGRAM) && !defined(TIME_SHARING)
# define MULTIPROGRAM_YIELD() yield()
#else
# define MULTIPROGRAM_YIELD()
#endif

#define NAME(key) \
  [AM_KEY_##key] = #key,

static const char *keyname[256] __attribute__((used)) = {
  [AM_KEY_NONE] = "NONE",
  AM_KEYS(NAME)
};

size_t serial_write(const void *buf, size_t offset, size_t len) {
  int l = 0;
  while (l < len){
    putch(*(char *)(buf+l));
    l++;
  }
  return l;
}

size_t events_read(void *buf, size_t offset, size_t len) {
 static bool has_kbd;
  has_kbd  = io_read(AM_INPUT_CONFIG).present;
  if (has_kbd) {
      AM_INPUT_KEYBRD_T ev = io_read(AM_INPUT_KEYBRD);
      if (!strcmp(keyname[ev.keycode],"NONE")){
	buf = "\0"; 
//	printf("none");
	return 0;
      }
      else{ 
//      printf("Got  (kbd): %s (%d) %s\n", keyname[ev.keycode], ev.keycode, ev.keydown ? "DOWN" : "UP");
      if (ev.keydown){
        memcpy(buf,"kd ",len);
      }
      else{
        memcpy(buf,"ku ",len); 
      }      
	strcat(buf,keyname[ev.keycode]);
        strcat(buf,"\n");
//      printf("buf%s\n",buf);
      }
   }
 return len;
/* AM_INPUT_KEYBRD_T ev = io_read(AM_INPUT_KEYBRD);
  if(ev.keycode == AM_KEY_NONE) {
    //memset(buf,0,len);
    return 0;
  }
  else{
    memset(buf,0,len);
    if(ev.keydown)
    {
      sprintf((char*)buf,"kd %s\n",keyname[ev.keycode]);
    }
    else sprintf((char*)buf,"ku %s\n",keyname[ev.keycode]);
    if(ev.keycode <= AM_KEY_F3 && ev.keycode >= AM_KEY_F1 && ev.keydown) {
      set_state(ev.keycode - 1);
    }
    return strlen((char*)buf);
}*/ 

}
static int width,height;
size_t dispinfo_read(void *buf, size_t offset, size_t len) {
 width = io_read(AM_GPU_CONFIG).width; 
 height = io_read(AM_GPU_CONFIG).height;
 sprintf(buf,"WIDTH:%d HEIGHT:%d",width,height);
 return len;
}

size_t fb_write(const void *buf, size_t offset, size_t len) {
//  io_write(AM_GPU_FBDRAW, 136+(offset/len)*width, 86+(offset/len)%width, (uint32_t *)buf, 128,len/(128*4), true);
//   printf("offset:%d,len:%d\n",offset,len);
 //  io_write(AM_GPU_FBDRAW, offset%(4 * width), offset/(4 * width), (uint32_t *)buf, len/4,1, true); 
 //printf one line a time
  int w = io_read(AM_GPU_CONFIG).width;
  int h = io_read(AM_GPU_CONFIG).height;
  int x = (offset/4)%w;
  int y = (offset/4)/w;
  if(offset+len > w*h*4) len = w*h*4 - offset;
  io_write(AM_GPU_FBDRAW,x,y,(uint32_t*)buf,len/4,1,true);
  assert(offset <= w*h*4);
 return len;
}

void init_device() {
  Log("Initializing devices...");
  ioe_init();
}
